//     __ _____ _____ _____
//  __|  |   __|     |   | |  JSON for Modern C++
// |  |  |__   |  |  | | | |  version 3.11.3
// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT

#pragma once

#include <cstddef>  // ptrdiff_t
#include <limits>   // numeric_limits
#include <nlohmann/detail/macro_scope.hpp>

NLOHMANN_JSON_NAMESPACE_BEGIN
namespace detail {

/*
@brief an iterator for primitive JSON types

This class models an iterator for primitive JSON types (boolean, number,
string). It's only purpose is to allow the iterator/const_iterator classes
to "iterate" over primitive values. Internally, the iterator is modeled by
a `difference_type` variable. Value begin_value (`0`) models the begin,
end_value (`1`) models past the end.
*/
class primitive_iterator_t {
 private:
  using difference_type = std::ptrdiff_t;
  static constexpr difference_type begin_value = 0;
  static constexpr difference_type end_value = begin_value + 1;

  JSON_PRIVATE_UNLESS_TESTED :
      /// iterator as signed integer type
      difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();

 public:
  constexpr difference_type get_value() const noexcept { return m_it; }

  /// set iterator to a defined beginning
  void set_begin() noexcept { m_it = begin_value; }

  /// set iterator to a defined past the end
  void set_end() noexcept { m_it = end_value; }

  /// return whether the iterator can be dereferenced
  constexpr bool is_begin() const noexcept { return m_it == begin_value; }

  /// return whether the iterator is at end
  constexpr bool is_end() const noexcept { return m_it == end_value; }

  friend constexpr bool operator==(primitive_iterator_t lhs,
                                   primitive_iterator_t rhs) noexcept {
    return lhs.m_it == rhs.m_it;
  }

  friend constexpr bool operator<(primitive_iterator_t lhs,
                                  primitive_iterator_t rhs) noexcept {
    return lhs.m_it < rhs.m_it;
  }

  primitive_iterator_t operator+(difference_type n) noexcept {
    auto result = *this;
    result += n;
    return result;
  }

  friend constexpr difference_type operator-(
      primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept {
    return lhs.m_it - rhs.m_it;
  }

  primitive_iterator_t &operator++() noexcept {
    ++m_it;
    return *this;
  }

  primitive_iterator_t operator++(int) & noexcept  // NOLINT(cert-dcl21-cpp)
  {
    auto result = *this;
    ++m_it;
    return result;
  }

  primitive_iterator_t &operator--() noexcept {
    --m_it;
    return *this;
  }

  primitive_iterator_t operator--(int) & noexcept  // NOLINT(cert-dcl21-cpp)
  {
    auto result = *this;
    --m_it;
    return result;
  }

  primitive_iterator_t &operator+=(difference_type n) noexcept {
    m_it += n;
    return *this;
  }

  primitive_iterator_t &operator-=(difference_type n) noexcept {
    m_it -= n;
    return *this;
  }
};

}  // namespace detail
NLOHMANN_JSON_NAMESPACE_END
